﻿using System.Diagnostics.CodeAnalysis;

namespace DimensionsHelper.CommandLine.ConsoleTracer;

/// <summary>
///     存储控制台的位置信息
/// </summary>
public readonly struct ConsolePosition : IEquatable<ConsolePosition>
{
    /// <summary>
    ///     行号，0开始
    /// </summary>
    public int Line { get; }


    /// <summary>
    ///     行位置
    /// </summary>
    public int Character { get; }


    private ConsolePosition(int line, int character)
    {
        Line = line;
        Character = character;
    }


    public static ConsolePosition Create(int line, int character)
    {
        return new ConsolePosition(line, character);
    }


    public override int GetHashCode()
    {
        return HashCode.Combine(Line, Character);
    }


    public bool Equals(ConsolePosition other)
    {
        return other.Line == Line && other.Character == Character;
    }

    public override bool Equals([NotNullWhen(true)] object? obj)
    {
        return obj is ConsolePosition position && Equals(position);
    }


    public static bool operator ==(ConsolePosition left, ConsolePosition right)
    {
        return left.Equals(right);
    }


    public static bool operator !=(ConsolePosition left, ConsolePosition right)
    {
        return !left.Equals(right);
    }


    public static bool operator >(ConsolePosition left, ConsolePosition right)
    {
        return left.Line > right.Line || (left.Line == right.Line && left.Character > right.Character);
    }


    public static bool operator >=(ConsolePosition left, ConsolePosition right)
    {
        return left.Line > right.Line || (left.Line == right.Line && left.Character >= right.Character);
    }


    public static bool operator <(ConsolePosition left, ConsolePosition right)
    {
        return left.Line < right.Line || (left.Line == right.Line && left.Character < right.Character);
    }


    public static bool operator <=(ConsolePosition left, ConsolePosition right)
    {
        return left.Line < right.Line || (left.Line == right.Line && left.Character <= right.Character);
    }
}


public readonly struct ConsoleLocation : IEquatable<ConsoleLocation>
{
    /// <summary>
    ///     起始位置
    /// </summary>
    public ConsolePosition Start { get; }


    /// <summary>
    ///     结束位置
    /// </summary>
    public ConsolePosition End { get; }


    /// <summary>
    ///     获取当前区间所包含的行数
    /// </summary>
    public int GetLines()
    {
        return End.Line - Start.Line + 1;
    }


    /// <summary>
    ///     如果此区间无效，将返回<see langword="false" />
    /// </summary>
    public bool Validate()
    {
        return End > Start;
    }


    private ConsoleLocation(ConsolePosition start, ConsolePosition end)
    {
        Start = start;
        End = end;
    }


    public static ConsoleLocation Create(ConsolePosition start, ConsolePosition end)
    {
        return new ConsoleLocation(start, end);
    }


    public override int GetHashCode()
    {
        return HashCode.Combine(Start.GetHashCode(), End.GetHashCode());
    }


    public bool Equals(ConsoleLocation other)
    {
        return Start.Equals(other.Start) && End.Equals(other.End);
    }


    public override bool Equals([NotNullWhen(true)] object? obj)
    {
        return obj is ConsoleLocation location && Equals(location);
    }


    public static bool operator ==(ConsoleLocation left, ConsoleLocation right)
    {
        return left.Equals(right);
    }


    public static bool operator !=(ConsoleLocation left, ConsoleLocation right)
    {
        return !left.Equals(right);
    }
}